﻿using System;
using System.Text;
using System.Collections.Generic;
using Microsoft.SharePoint;
using Kiiro.Common.Entities;
using Kiiro.Common.Utility;
using Kiiro.ExceptionManagement;

using SPListNames = Kiiro.Common.Utility.Constants.SPListNames;
using CommentFieldNames = Kiiro.Common.Utility.Constants.CommentFieldNames;

namespace Kiiro.DataAccess
{
    public class CommentDA
    {
        #region Singleton
        private CommentDA ( )
        {
        }

        private static CommentDA instance = null;
        private static readonly object threadLock = new object ( );

        public static CommentDA Instance
        {
            get
            {
                lock ( threadLock )
                {
                    if ( instance == null )
                    {
                        instance = new CommentDA ( );
                    }
                }
                return instance;
            }
        }
        #endregion

        public Comment GetById ( int commentId, Guid siteCollectionId, string serverRelativeUrl )
        {
            Comment comment = null;

            try
            {
                using ( SPWeb web = SPHelpers.GetWeb ( siteCollectionId, serverRelativeUrl ) )
                {
                    SPList list = web.GetList ( SPHelpers.GetServerRelativeUrl ( web ) + Constants.SPListUrls.Discussions );

                    if ( list != null )
                    {
                        SPListItem listItem = list.GetItemById ( commentId );
                        comment = SPDataHelpers.MakeComment ( listItem );
                    }
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( ex, true );
            }

            return comment;
        }

        /// <summary>
        /// Gets a list of Comment entities. If commentIds is null or empty this method returns ALL Comments.
        /// </summary>
        /// <param name="commentIds">The list of comment ids to get. If commentIds is null or empty this method returns ALL comments.</param>
        /// <param name="siteCollectionId">The site collection id</param>
        /// <param name="serverRelativeUrl">The server relative url</param>
        /// <returns>If commentIds is null or empty this method returns ALL comments.</returns>
        public List<Comment> GetCommentsByIds ( List<int> commentIds, Guid siteCollectionId, string serverRelativeUrl )
        {
            List<Comment> comments = new List<Comment> ( );
            SPList list = null;

            using (SPWeb web = SPHelpers.GetWeb(siteCollectionId, serverRelativeUrl))
            {
                list = web.Lists[SPListNames.Discussions];

                if (list != null)
                {
                    SPQuery query = new SPQuery();

                    bool first = true;
                    if (commentIds != null && commentIds.Count > 0)
                    {
                        foreach (int commentId in commentIds)
                        {
                            if (!first) query.Query = "<Or>" + query.Query;
                            query.Query += "<Eq><FieldRef Name='ID'/><Value Type='Integer'>" + commentId + "</Value></Eq>";
                            if (!first) query.Query += "</Or>";

                            first = false;
                        }
                    }

                    if (!string.IsNullOrEmpty(query.Query))
                        query.Query = "<Where>" + query.Query + "</Where>";

                    query.ItemIdQuery = true;

                    SPListItemCollection listItems = list.GetItems(query);
                    if (listItems != null)
                        foreach (SPListItem listItem in listItems)
                        {
                            try
                            {
                                comments.Add(SPDataHelpers.MakeComment(listItem));
                            }
                            catch (Exception ex)
                            {
                                ExceptionManager.HandleException(ex, false);
                            }
                        }
                }
            }

            return comments;
        }

        public List<Comment> GetByDiscussionId ( int discussionId, Guid siteCollectionId, string serverRelativeUrl )
        {
            List<Comment> comments = null;

            try
            {
                using ( SPWeb web = SPHelpers.GetWeb (siteCollectionId,serverRelativeUrl ) )
                {
                    StringBuilder queryText = new StringBuilder ( );
                    queryText.Append ( "<Where>" );
                    queryText.Append ( "  <Eq>" );
                    queryText.Append ( "    <FieldRef Name='" + CommentFieldNames.DiscussionId + "'/>" );
                    queryText.Append ( "    <Value Type='Integer'>" + discussionId + "</Value>" );
                    queryText.Append ( "  </Eq>" );
                    queryText.Append ( "</Where>" );

                    SPQuery query = new SPQuery ( );
                    query.Query = queryText.ToString ( );

                    SPList list = web.GetList ( SPHelpers.GetServerRelativeUrl ( web ) + Constants.SPListUrls.Discussions );

                    if ( list != null )
                    {
                        SPListItemCollection listItems = list.GetItems ( query );

                        if ( listItems != null && listItems.Count > 0 )
                        {
                            comments = new List<Comment> ( );
                            foreach ( SPListItem listItem in listItems )
                            {
                                foreach ( SPFolder subFolder in listItem.Folder.SubFolders )
                                {
                                    SPListItem subItem = subFolder.Item;
                                    Comment comment = new Comment ( );
                                    comment = SPDataHelpers.MakeComment ( listItem );
                                    comments.Add ( comment );
                                }
                            }
                        }
                    }
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( ex, true );
            }

            return comments;
        }

        public Comment Save ( Comment comment, Guid siteCollectionId, string serverRelativeUrl )
        {
            SPList list = null;
            SPListItem listItem = null;
            try
            {
                if ( comment == null )
                    throw new Exception ( "Cannot SaveComment() when Comment entity is null" );

                if ( comment.EditType != EditType.Unchanged )
                {
                    using (SPWeb web = SPHelpers.GetWeb(siteCollectionId, serverRelativeUrl))
                    {
                        list = web.Lists[Constants.SPListNames.Discussions];

                        if (list != null)
                        {
                            #region Get Item

                            if ( comment.EditType == EditType.Created )
                            {
                                SPListItem discussion = list.Folders.GetItemById ( comment.DiscussionId );
                                listItem = list.Folders.Add ( discussion.Folder.ServerRelativeUrl, SPFileSystemObjectType.Folder );
                            }
                            else
                            {
                                listItem = list.Folders.GetItemById ( comment.Id );
                            }

                            switch (comment.EditType)
                            {
                                case EditType.Created:
                                    listItem[Constants.CommentFieldNames.SiteCollectionId] = list.ParentWeb.Site.ID;

                                    if (comment.CreatedBy != null && comment.CreatedBy.Id > 0)
                                        listItem[CommentFieldNames.CreatedBy] = comment.CreatedBy.Id;
                                    if (comment.CreatedDate != null && comment.CreatedDate != DateTime.MinValue)
                                        listItem[CommentFieldNames.CreatedDate] = comment.CreatedDate;
                                    if (comment.ModifiedBy != null && comment.ModifiedBy.Id > 0)
                                        listItem[CommentFieldNames.ModifiedBy] = comment.ModifiedBy.Id;
                                    if (comment.ModifiedDate != null && comment.ModifiedDate != DateTime.MinValue)
                                        listItem[CommentFieldNames.ModifiedDate] = comment.ModifiedDate;

                                    break;

                                case EditType.Updated:
                                    if (comment.ModifiedBy != null && comment.ModifiedBy.Id > 0)
                                        listItem[CommentFieldNames.ModifiedBy] = comment.ModifiedBy.Id;
                                    if (comment.ModifiedDate != null && comment.ModifiedDate != DateTime.MinValue)
                                        listItem[CommentFieldNames.ModifiedDate] = comment.ModifiedDate;
                                    break;

                                case EditType.Deleted:
                                default:
                                    break;
                            }
                            #endregion

                            #region Set Item Properties

                            if (listItem != null && comment.EditType != EditType.Deleted)
                            {
                                if (comment.DiscussionId > 0)
                                    listItem[CommentFieldNames.DiscussionId] = comment.DiscussionId;

                                if (!string.IsNullOrEmpty(comment.Title))
                                    listItem[CommentFieldNames.Title] = comment.Title;

                                if (!string.IsNullOrEmpty(comment.Description))
                                    listItem[CommentFieldNames.Description] = comment.Description;

                                if (!string.IsNullOrEmpty(comment.Text))
                                    listItem[CommentFieldNames.Text] = comment.Text;
                            }
                            #endregion

                            #region Update / Delete Item
                            try
                            {
                                list.ParentWeb.AllowUnsafeUpdates = true;
                                if (comment.EditType == EditType.Deleted)
                                {
                                    list.Folders.DeleteItemById(listItem.ID);
                                }
                                else
                                {
                                    listItem.Update();
                                    comment = SPDataHelpers.MakeComment(listItem);
                                }
                            }
                            catch (Exception ex)
                            {
                                ExceptionManager.HandleException(ex, true);
                            }
                            finally
                            {
                                list.ParentWeb.AllowUnsafeUpdates = false;
                            }
                            #endregion
                        }
                    }
                }
            }
            catch ( Exception ex )
            {
                ExceptionManager.HandleException ( ex, true );
            }

            return comment;
        }
    }
}

/*************************************************************************
 * 
 * $Log: /Internal Projects/Kiiro/Kiiro.DataAccess/CommentDA.cs $
 * 
 * 14    2/08/10 5:04p Camerons
 * 
 * 13    1/25/10 1:17p Camerons
 * 
 * 12    1/12/10 12:02p Camerons
 * 
 * 11    26/11/09 10:35a Camerons
 * 
 * 10    17/11/09 6:46p Camerons
 * 
 * 9     22/09/09 6:03p Camerons
 * Code changes to support creating user on demand - version 1.1.x.x
 * 
 * 8     17/08/09 10:41a Camerons
 * Added check-in comments section
 * 
 ************************************************************************/